<!DOCTYPE html>
<html lang="zh-cn">
  <head>
    <meta charset="UTF-8">
    <title>Sucha's Blog - Archive for September, 2021</title>
    <meta name="generator" content="MarkdownProjectCompositor.lua">
    <meta name="author" content="Sucha">
    <meta name="keywords" content="suchang, programming, Linux, Lua">
    <meta name="description" content="Sucha's blog">
    <link rel="shortcut icon" href="../images/ico.png">
    <link rel="stylesheet" type="text/css" href="../styles/blog.css">
    <link rel="stylesheet" type="text/css" href="../styles/prism.min.css">
    <style id="site_theme"></style>
  </head>
  <body>
    <div id="body">
      <div id="text">
	   <!-- Page published by cmark-gfm begins here --><h1>Sucha's Blog ~ Archive for September, 2021</h1>
<p><a id="p0"></a></p>
<div class="date">21年9月30日 周四 23:59</div>
<h2>9 月份干嘛了</h2>
<p>其实 9 月份做了蛮多的事情，公司那边慢慢忙起来了，在公司里面做了一个数据库抽象模块，其实就是一个抽象的 DAO（Data Access Object），使用的是 GRDB，起因是使用的 Realm 版本太旧了，启动后未知原因的 crash 飙升，堆栈上看是启动时候 Realm 在初始化 ObjC 这一层某个 sub class 时候就挂了，都还没有任何 DB 的操作逻辑呢，其实就是 DidFinishLaunch 都没走完。</p>
<p>因为工程早就都是 Swift 了，不想呆在 ObjC 里面，太多的 swizzle 黑魔法，对工程代码质量要求太高，小公司很难保证。因为 DB 操作大部分都仅仅是序列化逻辑，上没有复杂的 join、foreign key 操作，所以只是简单封装了一下 GRDB，抽象独立为 Pod 库，不污染工程代码就好。基于这个前提，抽象了 fetch、push、watch 接口，Pod 内部建立内存模型跟 DB 模型的对应，其实就是表操作。可以通过上述的几个接口，接入不同的带 param 的 enum 参数，就可以完成功能。有了这一层抽象，后续即便 GRDB 因为各种原因不能使用，我们不需要修改业务代码，只需要在 Pod 这一层做内存到外存的转换就好。</p>
<p>另外还抽象了一个指定 key 的 JSONObject 模型，里面可以放入各种深度、层次的 JSON 数据，insert、update、delete、watch 时候，都关联到 key 上就好，对于一些需要序列化的数据，又不想用 UserDefault 来做，就可以使用这个 JSONObject 来存入 GRDB，实际上是作为 blob 数据存储进去的，目前只支持一个 key，一般都是什么什么 id 之类的，这也是目前能够支持绝大多数业务的序列化功能。</p>
<p>另外学写了一下 SPA（Single Page Application），Web 发展迭代速度要比移动 App 快多了，可选的很多，React、Vue、Preact 都有，我稍微摸索了一下 React，觉得有点拎不动，然后 Vue、Preact 也一样，再说这些东西依赖很重，nodejs 几乎是必须的，build 过程少不了，最后我选了 Mithril。之前有听说过，然后在<a href="http://www.ruanyifeng.com/blog/">阮一峰</a>那边又被推了一下。教程相对简单，而且是只支持 browser，不需要 build 过程，我学习了两三天，做了一个 Wiki 管理工具，用的 Markdown IDE 是 <a href="https://simplemde.com/">SimpleMDE Markdown Editor</a>。</p>
<p>选择 Mithril 的原因除了它自己吹嘘的之外，还有其他的考量，比如可以利用上之前的 HTTP Server <a href="https://github.com/lalawue/cincau">Cincau</a>。这个新作的 Wiki 管理工具，最后就作为了 Cincau 支持的一个 SPA Demo 页面。其实 SPA 对后端没什么依赖，后端主要是模版 SSR（Server Side Render）。当然有了这个 Wiki 工具，我就可以将之前另外一个小站点的 Wiki 移过来，直接在搭建在 Cincau 上面，话说之前的 Wiki 是 <a href="https://www.dokuwiki.org/">doku</a> + php + nginx 来搭建的，改成 Luajit + Cincau 后，资源依赖少了很多，不过相对功能也少了很多，这些坑只好自己趟了，对于我这个职业 App 开发者来说，也是一个学习的过程。</p>
<p>上面说到 SSR，因为不大喜欢之前搭配的 <a href="https://github.com/leafo/etlua">etlua</a>，于是自己做了 <a href="../blog/2021-08.html#p0">lua-html-tags</a>，这个之前 8 月份的时候提过了。</p>
<p>话说之前 doku 除了基本的 Wiki 功能（用得比较早，当时还不知道 CommonMark 或者 GFM 的语法），还有 revision，以及 show diff 的功能。我觉得这个功能挺好的，对于刚用 Mithril 做的 Wiki 工具来说，可以有效避免某些错误操作导致的 clear 逻辑（当然这从来就没发生过），对心理造成的压力，毕竟有 revision，我可以随时恢复到任何一个版本。</p>
<p>增量保存用的工具是 <a href="https://github.com/mendsley/bsdiff">bsdiff</a>，其实用系统里面自带的 GNU 的 diffutils 或者 patch 也是可以的，只是在 server 这一层，需要调用太多次 shell 脚本完成相应的功能，觉得不大好。于是将这两个工具做成了 Lua 库 <a href="https://github.com/lalawue/lua-bsdiff">lua-bsdiff</a>，并 apply 了两个觉得挺不错的 patch。</p>
<p>不过上面提到的 Wiki 支持 revision 功能，在 cincau 的 demo 上面是没有的，目前没打算开源，🙂</p>
<p>9 月份忘记写 blog 了，10 月初初回顾了一下，后面有时间再详细铺开，先这样吧，🤗</p>
<div class="category"><a href="CategoryLife.html">CategoryLife</a> / <a href="2021-09.html#p0">Permalink</a> / <a href="https://github.com/lalawue/homepage/discussions/categories/blog" target="_blank">Discussion</a></div>
<!-- Page published by cmark-gfm ends here -->
  <div id="foot">2004-<script>var d = new
	Date();document.write(d.getFullYear())</script> &copy;
	Sucha. Powered by MarkdownProjectCompositor.
  </div>
  </div><!-- text -->
  <div id="sidebar">
  </div><!-- sidebar -->
  <script src="../js/prism.min.js" async="async"></script>
  <script src="../js/blog_sidebar.js"></script>
  </div> <!-- body -->
</body>
</html>